package com.zack.util.nlp.tfidf;
/**
* author: dejian
* 2017  Sep 28, 2017  12:19:15 AM  (could be changed)
**/

import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.zack.util.multitype.file.ReadAndWriteFileFromDirectory;

/**
 * @author Administrator
 *
 *         统计tfidf： 通过file进行。file里词与词之间用 \t分割， doc与doc之间用DOC_SPLIT_MARK分开
 */
public class TFAllFromFile {

    // 如果所有doc 都在一个文件里，则doc与doc之间用这个进行分割。
    public static final String DOC_SPLIT_MARK = "\u2003\u2002\u2001";

    // 如果没有默认名则用数字和“doc” 组合
    private static int docIdGen = 0;
    // 如果没有默认名，则用默认名加 数字
    private static String defaultDocName = "doc";
    /**
     * Map<docName,Map<词语，词语在doc里出现的次数>>: 记录每个词在每一篇文章里的词频
     */
    public static Map<String, Map<String, Integer>> docTermFreqMap = new LinkedHashMap<>();
    // 记录每一篇文档的词数总数
    public static Map<String, Integer> docNameTermNumMap = new LinkedHashMap<>();
    
    
    
    // Map<词语，词语在corpus出现的次数> : 记录每个词在corpus里出现的次数
    public static Map<String, Integer> corpusTermFreqMap = new LinkedHashMap<>();
    
    public static int allWordNum = 0;
    
    /**
     * 第一种: 所有doc在一个文件夹里， 可以递归 统计整个corpus里的词频 注意，doc里一定是分好词的才行
     * 
     * @param dirPath
     */
    public static void tfAllFromDir(String dirPath) {
        List<String> filePaths = ReadAndWriteFileFromDirectory.getAllFilesPath(dirPath, "txt");
        for (String fileStringPath : filePaths) {
            String content = ReadAndWriteFileFromDirectory.readBigFileReturnContent(new File(fileStringPath));
            tfEachDoc(fileStringPath, content);
        }
    }

    /**
     * 第二种： corpus在一个文件里面 统计corpus 的词频， 会有 corpus的词频与 每一篇的词频，存在两个map里：
     * docTermFreqMap， corpusTermFreqMap 所有doc都在一个file里面进行统计。 注意，doc里一定是分好词的才行
     * 
     * @param corpusFilePath
     */
    public static void tfAllFromCorpusFile(String corpusFilePath) {
        File corpusfile = new File(corpusFilePath);
        String corpusContent = ReadAndWriteFileFromDirectory.readBigFileReturnContent(corpusfile);
        String[] docsContent = corpusContent.split(DOC_SPLIT_MARK);
        for (String cont : docsContent) {
            // 因为所有文档都存在一个file里。并且用分隔符分开， 因此没有预先的doc名。
            String docName = defaultDocName + "-" + (docIdGen++);
            tfEachDoc(docName, cont);
        }
    }

    /**
     * 记录每个doc以及doc里的term+freq
     * 
     * @param docName
     * @param eachDocContent
     */
    public static void tfEachDoc(String docName, String eachDocContent) {
        String[] termArr = eachDocContent.split("[\\s]+");
        Map<String, Integer> termFreqIndoc = new HashMap<>();

        // 如果map里已经有这个doc了，则就直接更新那个doc里面的内容
        if (docTermFreqMap.containsKey(docName)) {
            termFreqIndoc = docTermFreqMap.get(docName);
        }
        
        for (String term : termArr) {
            allWordNum++;
            // 记录每一个doc 的termFreq
            if (termFreqIndoc.containsKey(term)) {
                termFreqIndoc.put(term, (termFreqIndoc.get(term) + 1));
            } else {
                termFreqIndoc.put(term, 1);
            }
            // 记录总的termFreq
            if (corpusTermFreqMap.containsKey(term)) {
                corpusTermFreqMap.put(term, (corpusTermFreqMap.get(term) + 1));
            } else {
                corpusTermFreqMap.put(term, 1);
            }

        }
        if (!docTermFreqMap.containsKey(docName)) {
            docTermFreqMap.put(docName, termFreqIndoc);
        }
        docNameTermNumMap.put(docName, termArr.length);
    }
}
